package com.yuandian.customer.perception.controller;

import com.yuandian.api.customer_perception.po.SystemOverviewParams;
import com.yuandian.api.customer_perception.vo.BusinessOverviewListVo;
import com.yuandian.api.customer_perception.vo.SystemOverviewListVo;
import com.yuandian.bpm.common.core.util.R;
import com.yuandian.bpm.common.data.resolver.ParamResolver;
import com.yuandian.customer.perception.service.IMonitorOverviewService;
import com.yuandian.enums.TableNameEnum;
import com.yuandian.po.MultipleTableInfo;
import com.yuandian.utils.PageDataInfo;
import com.yuandian.utils.YDateUtil;
import com.yuandian.utils.poi.ExcelTableInfo;
import com.yuandian.utils.poi.ExcelTitleUtils;
import com.yuandian.utils.poi.ExcelUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.math.BigDecimal;
import java.text.ParseException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;

/**
 * <p>
 * 全系统监控总览
 * <p>
 *
 * @author lijunhang
 * @date 2021/8/11
 * @since 1.0.0
 */
@Slf4j
@Api(value = "全系统监控总览接口", tags = "全系统监控总览接口")
@Validated
@RestController
@RequestMapping("/system/monitorOverview")
public class MonitorOverviewController {


    @Autowired
    private IMonitorOverviewService monitorOverviewService;

/*
    @Autowired
    private ISysConfigService sysConfigService;	TODO 远程调用


    @Autowired
    private ISearchOptionService searchOptionService;	TODO 远程调用
*/



    /**
     * 全系统总览概况
     *
     * @param params 请求参数
     * @return 全系统总览概况数据
     */
    @ResponseBody
	@ApiOperation(value = "全系统监控总览-全系统总览概况", notes = "全系统监控总览-全系统总览概况")
	@PostMapping("/systemOverview")
    public R<Object> systemOverview(@RequestBody SystemOverviewParams params) {
		// 获取表信息集
		MultipleTableInfo info = new MultipleTableInfo();
		info.setTableName(TableNameEnum.ADS_BUSI_SYS_VISIT_TREND_M.getName());
		List<MultipleTableInfo> tableInfos = Collections.singletonList(info);

		// 查询系统健康度阈值和业务健康度阈值
		String systemThreshold = ParamResolver.getStr("sys.threshold.unhealth.system");
		String businessThreshold = ParamResolver.getStr("sys.threshold.unhealth.business");
		params.setSystemThreshold(systemThreshold);
		params.setBusinessThreshold(businessThreshold);

        return R.ok(monitorOverviewService.systemOverview(params, tableInfos));
    }


    /**
     * 全系统健康度top5 问题：健康度会出现负值，受理量减去告警量再除以受理量
     *
     * @param params 请求参数
     * @return 全系统健康度top5数据
     */
    @ResponseBody
	@ApiOperation(value = "全系统监控总览-全系统健康度top5 ", notes = "全系统监控总览-全系统健康度top5 ")
	@PostMapping("/systemHealthTop5")
    public R<Object> systemHealthTop5(@RequestBody SystemOverviewParams params) {
		// 获取表信息集
		MultipleTableInfo info = new MultipleTableInfo();
		info.setTableName(TableNameEnum.ADS_BUSI_SYS_VISIT_TREND_M.getName());
		List<MultipleTableInfo> tableInfos = Collections.singletonList(info);

        //默认值
        if (params.getIsAsc() == null || "".equals(params.getIsAsc())) {
            params.setIsAsc("desc");
        }
        params.setOrderByColumn("healthRate");
        return R.ok(monitorOverviewService.systemHealthAndVisistTop5(params, tableInfos));
    }


    /**
     * 全系统访问量top5
     *
     * @param params 请求参数
     * @return 全系统健康度top5数据
     */
    @ResponseBody
	@ApiOperation(value = "全系统监控总览-全系统访问量top5", notes = "全系统监控总览-全系统访问量top5")
	@PostMapping("/systemVisitTop5")
    public R<Object> systemVisitTop5(@RequestBody SystemOverviewParams params) {
 		// 获取表信息集
		MultipleTableInfo info = new MultipleTableInfo();
		info.setTableName(TableNameEnum.ADS_BUSI_SYS_VISIT_TREND_M.getName());
		List<MultipleTableInfo> tableInfos = Collections.singletonList(info);

		//默认值
        if (params.getIsAsc() == null || "".equals(params.getIsAsc())) {
            params.setIsAsc("desc");
        }
        params.setOrderByColumn("visitCount");
        return R.ok(monitorOverviewService.systemHealthAndVisistTop5(params, tableInfos));
    }


    /**
     * 全业务健康度top5
     *
     * @param params 请求参数
     * @return 全业务健康度top5数据
     */
    @ResponseBody
	@ApiOperation(value = "全系统监控总览-全业务健康度top5", notes = "全系统监控总览-全业务健康度top5")
	@PostMapping("/businessHealthTop5")
    public R<Object> businessHealthTop5(@RequestBody SystemOverviewParams params) {

		// 获取表信息集
		MultipleTableInfo info = new MultipleTableInfo();
		info.setTableName(TableNameEnum.ADS_BUSI_SYS_VISIT_TREND_M.getName());
		List<MultipleTableInfo> tableInfos = Collections.singletonList(info);

		//默认值
        if (params.getIsAsc() == null || "".equals(params.getIsAsc())) {
            params.setIsAsc("desc");
        }
        params.setOrderByColumn("healthRate");
        return R.ok(monitorOverviewService.businessHealthAndVisistTop5(params, tableInfos));
    }

    /**
     * 全业务访问量top5
     *
     * @param params 请求参数
     * @return 全业务健康度top5数据
     */
    @ResponseBody
	@ApiOperation(value = "全系统监控总览-全业务访问量top5", notes = "全系统监控总览-全业务访问量top5")
	@PostMapping("/businessVisitTop5")
    public R<Object> businessVisitTop5(@RequestBody SystemOverviewParams params) {

		// 获取表信息集
		MultipleTableInfo info = new MultipleTableInfo();
		info.setTableName(TableNameEnum.ADS_BUSI_SYS_VISIT_TREND_M.getName());
		List<MultipleTableInfo> tableInfos = Collections.singletonList(info);

		//默认值
        if (params.getIsAsc() == null || "".equals(params.getIsAsc())) {
            params.setIsAsc("desc");
        }
        params.setOrderByColumn("visitCount");
        return R.ok(monitorOverviewService.businessHealthAndVisistTop5(params, tableInfos));
    }

    /**
     * 全系统总览列表
     *
     * @param params 请求参数
     * @return 全系统总览列表数据
     */
    @ResponseBody
	@ApiOperation(value = "全系统监控总览-全系统总览列表", notes = "全系统监控总览-全系统总览列表")
	@PostMapping("/systemOverviewList")
    public R<Object> systemOverviewList(@RequestBody SystemOverviewParams params) {
		// 获取表信息集
		MultipleTableInfo info = new MultipleTableInfo();
		info.setTableName(TableNameEnum.ADS_BUSI_SYS_VISIT_TREND_M.getName());
		List<MultipleTableInfo> tableInfos = Collections.singletonList(info);

		//获取总览列表数据
        PageDataInfo pageDataInfo = monitorOverviewService.systemOverviewList(params, tableInfos);

        return R.ok(pageDataInfo);
    }


    /**
     * 全系统总览列表下载
     *
     * @param params 请求参数
     * @return 全系统总览列表下载
     */
	@ApiOperation(value = "全系统监控总览-全系统总览列表下载", notes = "全系统监控总览-全系统总览列表下载")
	@PostMapping("/systemOverviewListExport")
    public void systemOverviewListExprt(@RequestBody SystemOverviewParams params, HttpServletResponse response) throws IOException, ParseException {

		// 获取表信息集
		MultipleTableInfo info = new MultipleTableInfo();
		info.setTableName(TableNameEnum.MYSQL_BUSI_SYS_DETAIL_STAT.getName());
		List<MultipleTableInfo> tableInfos = Collections.singletonList(info);

		String title = "全系统总览列表";

        List<String> titleParams = new ArrayList<>();
        titleParams.add(title);
        if (params.getAreaCode() != null && params.getAreaCode() != ""){
//            titleParams.add(searchOptionService.queryAreaName(params.getAreaCode()));	TODO 远程调用
        }
        String formTitleName = ExcelTitleUtils.formTitleName(titleParams,params.getStartTime(),params.getEndTime());

        List<SystemOverviewListVo> list = new ArrayList<>();
        try {
            list = monitorOverviewService.systemOverviewListExport(params,tableInfos);
        } catch (Exception e) {
            log.error("所选时间表不存在!但表格需要正常导出.");
        }

        //设置序号
        int index = 1;
        for (SystemOverviewListVo systemOverviewListVo : list) {
            systemOverviewListVo.setId(index++);
        }
        list.forEach(systemOverviewListVo -> {
            if (systemOverviewListVo.getAvgResponseTime() == null) {
                systemOverviewListVo.setAvgResponseTime("0.00毫秒");
            } else {
                systemOverviewListVo.setAvgResponseTime(YDateUtil.getMinSecond(getDouble(Double.parseDouble(systemOverviewListVo.getAvgResponseTime()) / 1000)));
            }
            systemOverviewListVo.setSuccessRate(systemOverviewListVo.getSuccessRate() + "%");
            systemOverviewListVo.setHealthRate(systemOverviewListVo.getHealthRate() + "%");
        });


        List<List<String>> headList = new ArrayList<>();
        List<String> titleList = Arrays.asList("序号", "系统名称", "系统业务量", "访问量", "受理量", "告警访问量", "失败访问量", "平均响应时长", "成功率", "健康度");
        titleList.forEach(s -> {
            List<String> childHeadList = new ArrayList<>();
            childHeadList.add(formTitleName);
            childHeadList.add(s);
            headList.add(childHeadList);
        });

        ExcelUtil.writeExcel(SystemOverviewListVo.class, "", title, list, headList, response);
    }

    /**
     * 业务总览列表
     *
     * @param params 请求参数
     * @return 业务总览列表数据
     */
    @ResponseBody
	@ApiOperation(value = "全系统监控总览-业务总览列表", notes = "全系统监控总览-业务总览列表")
	@PostMapping("/businessOverviewList")
    public R<Object> businessOverviewList(@RequestBody SystemOverviewParams params) {
		// 获取表信息集
		MultipleTableInfo info = new MultipleTableInfo();
		info.setTableName(TableNameEnum.ADS_BUSI_SYS_VISIT_TREND_M.getName());
		List<MultipleTableInfo> tableInfos = Collections.singletonList(info);

		PageDataInfo pageDataInfo = monitorOverviewService.businessOverviewList(params, tableInfos);
        return R.ok(pageDataInfo);
    }

    /**
     * 业务总览列表下载
     *
     * @param params 请求参数
     * @return 全系统总览列表下载
     */
    @ResponseBody
	@ApiOperation(value = "全系统监控总览-业务总览列表下载", notes = "全系统监控总览-业务总览列表下载")
	@PostMapping("/businessOverviewListExport")
    public void businessOverviewListExport(@RequestBody SystemOverviewParams params, HttpServletResponse response) throws IOException {
		// 获取表信息集
		MultipleTableInfo info = new MultipleTableInfo();
		info.setTableName(TableNameEnum.MYSQL_BUSI_SYS_DETAIL_STAT.getName());
		List<MultipleTableInfo> tableInfos = Collections.singletonList(info);

		List<BusinessOverviewListVo> list = new ArrayList<>();
        try {
            list = monitorOverviewService.businessOverviewListExport(params, tableInfos);
        } catch (Exception e) {
            log.error("所选时间表不存在!但表格需要正常导出.");
        }

        String title = "业务总览列表";
        List<String> titleParams = new ArrayList<>();
        titleParams.add(title);
//        titleParams.add(searchOptionService.querySystemName(params.getSystemId()));	TODO 远程调用
        if (params.getAreaCode() != null && params.getAreaCode() != ""){
//            titleParams.add(searchOptionService.queryAreaName(params.getAreaCode()));	TODO 远程调用
        }
        List<String> titleList = Arrays.asList("序号", "业务名称", "访问量", "受理量", "告警访问量", "失败访问量", "平均办理时长", "平均响应时长", "成功率", "健康度");

        ExcelTableInfo build = new ExcelTableInfo.Builder(params, BusinessOverviewListVo.class)
                .setTitle(titleParams)
                .setHeader(titleList)
                .setDataList(list)
                .setNumberName("id")
                .setSuffixPercentageFields("successRate", "healthRate")
                .setTimeFormatFields("avgResponseTime","avgVisitTime")
                .build();
        build.exportExcel(response);
    }

    /**
     * 查询地市id和名称
     * @param params 请求参数
     * @return 查询地市id和名称
     */
    @ResponseBody
	@ApiOperation(value = "全系统监控总览-查询地市id和名称", notes = "全系统监控总览-查询地市id和名称")
	@PostMapping("/queryAreaCodeAndName")
    public R<Object> queryAreaCodeAndName(@RequestBody SystemOverviewParams params) {
        return R.ok(monitorOverviewService.queryAreaCodeAndName(params));
    }


    public static Double getDouble(Double allTime) {
        if (allTime == null) { return 0d; }
        return new BigDecimal(allTime).setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue();
    }

}
